package fun.codedesign.jdk.math.reverse;

import org.junit.Assert;
import org.junit.Test;

public class Reverse {
    /**
     * 对一个String字符串原地反转
     */
    public static void main(String[] args) {
        System.out.println(reverse("abcdef"));
    }

    /**
     * 使用StringBuilder 对字符串遍历，然后赋值，返回一个新的逆序String
     *
     * @param word
     * @return
     */
    public static String reverse(final String s) {
        final StringBuilder sb = new StringBuilder(s.length());
        for (int i = s.length() - 1; i >= 0; i--) {
            sb.append(s.charAt(i));
        }
        return sb.toString();
    }

    /**
     * 如果反转的数据有几个GB，则以上方法存在效率问题，可以用以下
     * <p>
     * 将字符串整个加入到StringBuilder中，然后针对StringBuilder中相同距离的字符进行交换
     * 0 1 2   length()-0-1 = 2
     *
     * <p> 在内存堆中处理比非堆中处理更加效率
     *
     * @param s
     * @return
     */
    public static String inPlaceReverse(final String s) {
        final StringBuilder builder = new StringBuilder(s);
        // 循环一半的次数,相同距离的交换，中间的保留
        for (int i = 0; i < builder.length() / 2; i++) {
            // 加入中间值进行交换
            final char temp = builder.charAt(i);
            final int otherEnd = builder.length() - i - 1;
            builder.setCharAt(i, builder.charAt(otherEnd));
            builder.setCharAt(otherEnd, temp);
        }
        return builder.toString();
    }

    @Test
    public void testReverse() throws Exception {
        Assert.assertEquals("fedcba", reverse("abcdef"));
    }

    @Test
    public void testInplaceReverse() throws Exception {
        Assert.assertEquals("nmkjihgfedcba", inPlaceReverse("abcdefghijkmn"));
    }
}
